package com.example.moveclock.common;

import com.example.moveclock.views.JoystickView;

import android.os.Handler;
import android.os.Message;
import android.widget.AnalogClock;
import android.widget.RelativeLayout;

public class TimeHandler extends Handler {
	private static double SPEED_MULTIPLIER = 2;
	private static double SPEED_ACCELERATION = 0.05;
	private static double SPEED_SLOWDOWN = 0.0125;
	private static double MAX_SPEED = 2;

	private AnalogClock clock;

	private double upSpeed = 0;
	private double downSpeed = 0;
	private double leftSpeed = 0;
	private double rightSpeed = 0;

	private float moveUp = 0;
	private float moveDown = 0;
	private float moveLeft = 0;
	private float moveRight = 0;

	private double xPosition;
	private double yPosition;
	private JoystickView joystick;
	private RelativeLayout rlayout;

	public void handleMessage(Message msg) {

		moveUp = joystick.getMoveJoystickUp();
		moveDown = joystick.getMoveJoystickDown();
		moveLeft = joystick.getMoveJoystickLeft();
		moveRight = joystick.getMoveJoystickRight();
		// use radius???
		upSpeed = calculateSpeed(moveUp, upSpeed);
		downSpeed = calculateSpeed(moveDown, downSpeed);
		leftSpeed = calculateSpeed(moveLeft, leftSpeed);
		rightSpeed = calculateSpeed(moveRight, rightSpeed);
		calculatePositionXY();
		stopIfObjectReachBorder();

		clock.layout((int) xPosition, (int) yPosition,
				(int) xPosition + clock.getWidth(),
				(int) yPosition + clock.getHeight());
	}

	private void stopIfObjectReachBorder() {
		if (xPosition < rlayout.getLeft()) {
			xPosition = rlayout.getLeft();
			if (leftSpeed - rightSpeed > 0.8 * SPEED_MULTIPLIER) {
				rightSpeed = leftSpeed * 0.5;
			}
			leftSpeed = 0;
		}
		if (yPosition < rlayout.getTop()) {
			yPosition = rlayout.getTop();
			if (upSpeed - downSpeed > 0.8 * SPEED_MULTIPLIER) {
				downSpeed = upSpeed * 0.5;
			}
			upSpeed = 0;
		}
		if (xPosition + clock.getWidth() > rlayout.getRight()) {
			xPosition = rlayout.getRight() - clock.getWidth();
			if (rightSpeed - leftSpeed > 0.8 * SPEED_MULTIPLIER) {
				leftSpeed = rightSpeed * 0.5;
			}
			rightSpeed = 0;
		}
		if (yPosition + clock.getHeight() > rlayout.getBottom()) {
			yPosition = rlayout.getBottom() - clock.getHeight();
			if (downSpeed - upSpeed > 0.8 * SPEED_MULTIPLIER) {
				upSpeed = downSpeed * 0.5;
			}
			downSpeed = 0;
		}
	}

	private void calculatePositionXY() {
		if (yPosition == 0) {
			yPosition = clock.getTop();
		}
		// yPosition = calculatePositionForCurrentSpeedWithSlowdown();
		yPosition = yPosition
				+ (downSpeed * (moveDown != 0 ? 1 + moveDown : 1) - upSpeed
						* (moveUp != 0 ? 1 + moveUp : 1));

		if (xPosition == 0) {
			xPosition = clock.getLeft();
		}
		xPosition = xPosition
				+ (rightSpeed * (moveRight != 0 ? 1 + moveRight : 1) - leftSpeed
						* (moveLeft != 0 ? 1 + moveLeft : 1));
	}

	private double calculateSpeed(double moveRatio, double currentSpeed) {
		double calculatedSpeed = currentSpeed;
		if (moveRatio > 0 && currentSpeed < MAX_SPEED * SPEED_MULTIPLIER) {
			calculatedSpeed = (currentSpeed + SPEED_ACCELERATION
					* SPEED_MULTIPLIER);
		} else if (moveRatio == 0) {
			// add slowdown to another variable
			calculatedSpeed = currentSpeed - SPEED_SLOWDOWN * SPEED_MULTIPLIER;
		}
		if (calculatedSpeed < 0) {
			calculatedSpeed = 0;
		}
		return calculatedSpeed;
	}

	public void setClock(AnalogClock clockToSet) {
		clock = clockToSet;
	}

	public void setJoystick(JoystickView joystick) {
		this.joystick = joystick;
	}

	public void setRlayout(RelativeLayout rlayout) {
		this.rlayout = rlayout;
	}

};